﻿using System;
using System.Collections.Generic;
using NHibernate.Mapping.ByCode;
using Xenta.Enums;

namespace Xenta.Entities
{
    /// <summary>
    /// Represents the stock entry entity.
    /// </summary>
    /// <remarks><pre>
    /// The entity regarding the disclosure level.
    /// 
    /// + Entire
    ///  + Extended
    ///   + Base
    ///    | - AdjustmentMin
    ///    | - AdjustmentMax
    ///    | - ExhaustionThreshold
    ///    | - Reserve
    ///    | - Flags
    ///    | - UpdatedOn
    ///    | - CreatedOn
    ///    + Keys
    ///     + Primary
    ///      | - EntityID
    ///      | - Item(of the Keys level)
    /// 
    /// Note: upper level includes lower level.
    /// </pre></remarks>
    public class StockEntryEntity : AuditableEntity
    {
        #region Fields

        private decimal _adjustmentMin;
        private decimal _adjustmentMax;
        private decimal _exhaustionThreshold;

        #endregion

        #region Ctors

        /// <summary>
        /// Initializes a new class instance.
        /// </summary>
        public StockEntryEntity()
        {
            _adjustmentMin = 1;
            _adjustmentMax = 1000;
            _exhaustionThreshold = 10;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the item.
        /// </summary>
        public virtual SalesItemEntity Item
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the minimum adjustment quantity.
        /// </summary>
        public virtual decimal AdjustmentMin
        {
            get
            {
                return _adjustmentMin;
            }
            set
            {
                _adjustmentMin = value;
            }
        }

        /// <summary>
        /// Gets or sets the maximum adjustment quantity.
        /// </summary>
        public virtual decimal AdjustmentMax
        {
            get
            {
                return _adjustmentMax;
            }
            set
            {
                _adjustmentMax = value;
            }
        }

        /// <summary>
        /// Gets or sets the reserve quantity.
        /// </summary>
        public virtual decimal Reserve
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the exhaustion threshold.
        /// </summary>
        public virtual decimal ExhaustionThreshold
        {
            get
            {
                return _exhaustionThreshold;
            }
            set
            {
                _exhaustionThreshold = value;
            }
        }

        /// <summary>
        /// Gets or sets the flags.
        /// </summary>
        public virtual StockEntryFlags Flags
        {
            get;
            set;
        }

        #endregion

        #region Utilities

        protected override void Disclose(IDictionary<String, Object> obj,
            DisclosureLevel level,
            IDictionary<String, String> options)
        {
            base.Disclose(obj, level, options);
            if(level >= DisclosureLevel.Primary)
                obj["Item"] = Item.Disclose(DisclosureLevel.Keys, options);
            if(level >= DisclosureLevel.Base)
            {
                obj["AdjustmentMin"] = AdjustmentMin;
                obj["AdjustmentMax"] = AdjustmentMax;
                obj["ExhaustionThreshold"] = ExhaustionThreshold;
                obj["Reserve"] = Reserve;
                obj["Flags"] = Flags.ToString();
            }
        }

        #endregion
    }

    /// <summary>
    /// The entity NHibernate mapper.
    /// </summary>
    public class StockEntryMapping : EntityMapping<StockEntryEntity>
    {
        /// <summary>
        /// Initializes a new class instance.
        /// </summary>
        public StockEntryMapping()
        {
            Table("fwk_StockEntries");
            Id(x => x.EntityID, m =>
            {
                m.Column("EntryID");
                m.Generator(Generators.Identity);
            });
            ManyToOne(x => x.Item, m =>
            {
                m.Column("ItemID");
                m.ForeignKey("FK_fwk_StockEntries_fwk_SalesItems");
                m.Index("IX_fwk_StockEntries");
                m.NotNullable(true);
                m.Fetch(FetchKind.Join);
            });
            Property(x => x.AdjustmentMin, m =>
            {
                m.Precision(19);
                m.Scale(4);
                m.NotNullable(true);
            });
            Property(x => x.AdjustmentMax, m =>
            {
                m.Precision(19);
                m.Scale(4);
                m.NotNullable(true);
            });
            Property(x => x.Reserve, m =>
            {
                m.Precision(19);
                m.Scale(4);
                m.NotNullable(true);
            });
            Property(x => x.ExhaustionThreshold, m =>
            {
                m.Precision(19);
                m.Scale(4);
                m.NotNullable(true);
            });
            Property(x => x.Flags, m =>
            {
                m.NotNullable(true);
            });
            Property(x => x.CreatedOn, m =>
            {
                m.NotNullable(true);
            });
            Property(x => x.UpdatedOn, m =>
            {
                m.NotNullable(true);
            });
        }
    }
}
